<!--
 * @Description: 
 * @Author: Xiaochuan-W
 * @Date: 2023-04-24 15:02:44
 * @LastEditors: Xiaochuan-W
 * @LastEditTime: 2024-09-06 17:43:59
-->
<template>
	<XConfigProvider>
		<header v-if="!hideHeader" :class="[expandSearch?'x-expand-header x-header':'x-header']">
			<div class="x-header-box">
				<slot name="header"></slot>
				<div :class="{ 'x-btns': true, 'active-btns': expandSearch }">
					<el-button
						v-if="!expandSearch"
						class="x-search x-btn"
						:icon="Search"
						type="primary"
						@click="search('search')"
					>
						查询
					</el-button>
					<el-button
						v-if="!expandSearch"
						:icon="Refresh"
						plain
						type="primary"
						@click="search('reset')"
					>
						重置
					</el-button>
					<el-button v-if="searchVisible" type="primary" @click="advancedSearch">
						高级搜索
						<el-icon :class="{ 'x-DArrowRight': true, 'x-expand': expandSearch }">
							<DArrowRight />
						</el-icon>
					</el-button>
				</div>
			</div>
			<div v-if="expandSearch" class="x-expand-btns">
				<el-button
					class="x-search x-btn"
					:icon="Search"
					type="primary"
					@click="search('search')"
				>
					查询
				</el-button>
				<el-button :icon="Refresh" plain type="primary" @click="search('reset')">
					重置
				</el-button>
			</div>
		</header>
		<section>
			<template v-if="!hideTitle">
				<div class="x-title">
					<slot name="title">列表</slot>
				</div>
				<div class="x-dashed"></div>
			</template>
			<div
				:style="{
					display: 'flex',
					justifyContent: 'flex-end',
					marginBottom: '14px'
				}"
			>
				<slot name="top"></slot>
			</div>
			<el-table
				v-if="tableFlag"
				ref="refTable"
				:data="data"
				:stripe="$attrs.stripe === undefined ? true : ($attrs.stripe as boolean)"
				:border="$attrs.border === undefined ? true : ($attrs.border as boolean)"
				:row-key="$attrs['row-key'] as string || 'id'"
				:tooltip-effect="$attrs['tooltip-effect'] as string || 'light'"
				v-bind="$attrs"
			>
				<template v-for="(item,index) in columns" :key="index">
					<el-table-column
						v-if="item.type === 'selection' && (item.show ? item.show() : true)"
						type="selection"
						:width="item.width"
						:align="item.align || 'center'"
						:fixed="item.fixed"
						:selectable="item.selectable"
						:reserve-selection="item['reserve-selection'] || true"
						:formatter="
							item.formatter &&
							((row: any, column: any, cellValue: any, index: any) =>
							(item.formatter as any)(row, column, cellValue, index))
						"
					/>
					<el-table-column
						v-else-if="item.type === 'expand' && (item.show ? item.show() : true)"
						type="expand"
						:width="item.width"
						:align="item.align || 'center'"
						:fixed="item.fixed"
					>
						<template #default="scope">
							<slot
								:name="item.slot || 'expand'"
								:row="scope.row"
								:index="scope.$index"
							/>
						</template>
					</el-table-column>
					<el-table-column
						v-else-if="item.type === 'index' && (item.show ? item.show() : true)"
						type="index"
						:index="item.index"
						:width="item.width"
						:label="item.label"
						:align="item.align || 'center'"
						:fixed="item.fixed"
						:formatter="
							item.formatter &&
							((row: any, column: any, cellValue: any, index: any) =>
								(item.formatter as any)(row, column, cellValue, index))
						"
						:min-width="item['min-width']"
					/>
					<el-table-column
						v-else-if="item.type === 'action' && (item.show ? item.show() : true)"
						:width="item.width"
						:label="item.label || '操作'"
						:align="item.align || 'center'"
						:fixed="item.fixed || 'right'"
						:min-width="item['min-width']"
					>
						<template #default="scope">
							<template v-for="(btn, ind) in item.list" :key="ind">
								<template v-if="!btn.children">
									<el-tooltip
										v-if="btn.title"
										effect="dark"
										:content="btn.title"
										placement="top"
									>
										<el-button
											v-if="btn.show ? btn.show(scope.row, scope.$index) : true"
											v-permission="btn.permission"
											v-bind="btn"
											:disabled="
												btn.disabled ? btn.disabled(scope.row, scope.$index) : false
											"
											@click.stop="
												btn.click
													? btn.click(scope.row, scope.$index)
													: 'javascript'
											"
										>
											{{ btn.label }}
										</el-button>
									</el-tooltip>
									<template v-else>
										<el-button
											v-if="btn.show ? btn.show(scope.row, scope.$index) : true"
											v-permission="btn.permission"
											v-bind="btn"
											:disabled="
												btn.disabled ? btn.disabled(scope.row, scope.$index) : false
											"
											@click.stop="
												btn.click
													? btn.click(scope.row, scope.$index)
													: 'javascript'
											"
										>
											{{ btn.label }}
										</el-button>
									</template>
								</template>
								<template v-else>
									<el-dropdown
										v-if="btn.show ? btn.show(scope.row, scope.$index) : true"
										v-permission="btn.permission"
										style="margin-left: 12px"
									>
										<el-button
											v-bind="btn"
											:disabled="
												btn.disabled ? btn.disabled(scope.row, scope.$index) : false
											"
										>
											更多
											<el-icon style="vertical-align: top">
												<ArrowDown />
											</el-icon>
										</el-button>
		
										<template #dropdown>
											<el-dropdown-menu>
												<el-dropdown-item
													v-for="(dropdownItem, inx) in btn.children"
													:key="inx"
													:disabled="
														dropdownItem.disabled
															? dropdownItem.disabled(scope.row, scope.$index)
															: false
													"
													@click.stop="
														dropdownItem.click
															? dropdownItem.click(scope.row, scope.$index)
															: 'javascript'
													"
												>
													<span
														v-if="
															dropdownItem.show
																? dropdownItem.show(scope.row, scope.$index)
																: true
														"
														v-permission="dropdownItem.permission"
													>
														{{ dropdownItem.label }}
													</span>
												</el-dropdown-item>
											</el-dropdown-menu>
										</template>
									</el-dropdown>
								</template>
							</template>
						</template>
					</el-table-column>
					<template v-else>
						<el-table-column
							v-if="item.slot && (item.show ? item.show() : true)"
							show-overflow-tooltip
							:width="item.width"
							:label="item.label"
							:align="item.align || 'center'"
							:fixed="item.fixed"
							:min-width="item['min-width']"
						>
							<template #default="scope">
								<slot :name="item.slot" :row="scope.row" :index="scope.$index" />
							</template>
						</el-table-column>
						<el-table-column
							v-if="!item.slot && (item.show ? item.show() : true)"
							show-overflow-tooltip
							:width="item.width"
							:label="item.label"
							:prop="item.prop"
							:align="item.align || 'center'"
							:fixed="item.fixed"
							:formatter="
								item.formatter &&
								((row: any, column: any, cellValue: any, index: any) =>
								(item.formatter as any)(row, column, cellValue, index))
							"
							:min-width="item['min-width']"
						/>
					</template>
				</template>
			</el-table>
			<div
				:style="{
					marginTop: '20px',
					display: 'flex',
					justifyContent: pagination.align || 'center'
				}"
			>
				<el-pagination
					v-if="pagination.show === undefined ? true : pagination.show"
					background
					:layout="pagination.layout || 'total,prev,pager,next,sizes,jumper'"
					:total="pagination.total"
					:current-page="page.page"
					:page-size="page.size"
					:page-sizes="pagination['page-sizes'] || [10, 20, 30, 40]"
					:teleported="false"
					@size-change="changeSize"
					@current-change="changeCurrent"
				/>
			</div>
		</section>
	</XConfigProvider>
</template>

<script setup lang="ts">
import XConfigProvider from '../XConfigProvider/index.vue'
import {ref,reactive,onMounted,watch,useAttrs,nextTick,DirectiveBinding} from 'vue'
import {ElButton,ElIcon,ElTable,ElTableColumn,ElLink,ElDropdown,ElDropdownItem,ElDropdownMenu,ElPagination,ElTooltip } from 'element-plus'
import {
	ArrowDown,
	Search,
	Refresh,
	DArrowRight
} from '@element-plus/icons-vue';
import { TableColumns } from './index.d';

const refTable = ref<any>();

const props = defineProps({
	hideHeader: {
		type: Boolean,
		default: false
	},
	hideTitle: {
		type: Boolean,
		default: false
	},
	data: {
		type: Array,
		default: () => []
	},
	// 表格例属性
	columns: {
		type: Array<TableColumns>,
		default: () => []
	},
	// 分页属性
	pagination: {
		type: Object,
		default: () => ({total:0})
	}
});
const page = reactive({
	page: props.pagination['current-page'] || 1,
	size: props.pagination['page-size'] || 10
});

function changeSize(val: number) {
	page.size = val;
	page.page = 1;
	props.pagination['search-data'](page.page, page.size, 'page');
}
function changeCurrent(val: number) {
	page.page = val;
	props.pagination['search-data'](page.page, page.size, 'page');
}
function search(flag: string) {
	page.page = 1;
	props.pagination['search-data'](page.page, page.size, flag);
}
function clearSelection() {
	refTable.value.clearSelection();
}
defineExpose({ clearSelection, refTable });

const expandSearch = ref(false);
function advancedSearch() {
	expandSearch.value = !expandSearch.value;
}

// 进入页面获取x-header-box高度，超出显示高级搜索
const searchVisible = ref(false);
onMounted(() => {
	const div = document.querySelector('.x-header-box') as HTMLElement;
	if (div && div.clientHeight > 62) {
		searchVisible.value = true;
	}
});
const tableFlag = ref(true);
const attrs = useAttrs();
watch(
	() => attrs['default-expand-all'],
	() => {
		tableFlag.value = false;
		nextTick(() => {
			tableFlag.value = true;
		});
	}
);

const vPermission = {
	mounted(el: Element, binding: DirectiveBinding) {
		const permissions = JSON.parse(localStorage.getItem('permissions') as string) || [];
		let hasPermission = true;
		if (binding.value) {
			hasPermission = binding.value.some((val: string) => {
				return permissions.includes(val);
			});
		}
		if (!hasPermission) {
			el.remove();
		}
	}
};
</script>

<style lang="scss" scoped>
@import 'element-plus/dist/index.css';
.x-header {
	background: #fff;
	border-radius: 6px;
	margin-bottom: 10px;
	padding: 20px 20px 0px;
	box-shadow: 0px 10px 10px 0px #e6eaed;
	height: 70px;
	overflow: hidden;
	.x-search {
		background-color: #2f9aff;
	}
	.x-header-box {
		display: flex;
		justify-content: space-between;
		.x-btns {
			flex: 0 0 320px;
			display: flex;
			justify-content: flex-end;
		}

		.x-DArrowRight {
			margin-left: 4px;
			transform: rotate(90deg);
		}
		.x-expand {
			transform: rotate(270deg);
		}
	}
	.x-expand-btns {
		display: flex;
		justify-content: center;
		padding-bottom: 14px;
	}
}
.x-expand-header {
	height: auto;
}
section {
	background: #fff;
	border-radius: 6px;
	overflow: hidden;
	padding: 20px;
	box-shadow: 0px 10px 10px 0px #e6eaed;
	.x-title {
		color: #2f9aff;
		font-family: SourceHanSansCN-Bold, SourceHanSansCN;
		position: relative;
		display: flex;
		justify-content: flex-start;
		padding-left: 8px;
		font-size: 16px;
		margin-bottom: 4px;

		&::before {
			content: '';
			width: 4px;
			height: 18px;
			background: #2f9aff;
			position: absolute;
			left: 0;
			top: 2px;
		}
	}
	.x-dashed {
		height: 4px;
		background-image: url('../images/dashed-bg.png');
		margin-bottom: 14px;
	}
}
</style>
